package com.only4play.web.resources;

import com.only4play.auth.AuthenticatedUser;
import com.only4play.constant.Oauth2Constant;
import com.only4play.constant.SSOConstant;
import com.only4play.domain.model.LogoutModel;
import com.only4play.domain.model.PasswordLoginModel;
import com.only4play.service.UserService;
import com.only4play.session.SessionManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;

/**
 * 登录资源（restfull接口）
 *
 * @author liyuncong
 * @date 2023/11/20 14:17
 **/

@Slf4j
@Controller
@RequestMapping()
public class LoginController extends AbstractBaseResource {

    @Autowired
    private UserService userService;
    @Autowired
    private SessionManager sessionManager;


    /**
     * 未登录时，重定向到认证服务器登录页面
     *
     * @param redirectUri 原客户端访问地址
     * @param appId       appId
     * @param request     请求
     * @return 登录页面
     */
    @GetMapping(SSOConstant.LOGIN_URL)
    public ModelAndView login(
        @RequestParam(value = SSOConstant.REDIRECT_URI, required = false) String redirectUri,
        @RequestParam(value = Oauth2Constant.APP_ID, required = false) String appId,
        HttpServletRequest request
    ) {
        request.setAttribute(SSOConstant.REDIRECT_URI, redirectUri);
        request.setAttribute(Oauth2Constant.APP_ID, appId);
        ModelAndView loginView = new ModelAndView();
        loginView.setViewName(SSOConstant.LOGIN_PATH);
        return loginView;
    }

    /**
     * 登录成功后，未指定重定向页面时，重定向到认证服务器登出页面
     *
     * @param redirectUri 原客户端访问地址
     * @param code        code
     * @param request     请求
     * @return 登出页面
     */
    @GetMapping(SSOConstant.LOGOUT_URL)
    public ModelAndView logout(
        @RequestParam(value = SSOConstant.REDIRECT_URI, required = false) String redirectUri,
        @RequestParam(value = Oauth2Constant.AUTH_CODE, required = false) String code,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws IOException {
        if (StringUtils.isBlank(code)) {
            // 重定向到登录页面
            response.sendRedirect(SSOConstant.LOGIN_URL);
        }
        request.setAttribute(SSOConstant.REDIRECT_URI, redirectUri);
        request.setAttribute(Oauth2Constant.AUTH_CODE, code);
        ModelAndView loginView = new ModelAndView();
        loginView.setViewName(SSOConstant.LOGOUT_PATH);
        return loginView;
    }

    /**
     * 登录认证，并重定向到原始调用地址
     *
     * @param loginModel 登录参数
     * @param request    请求
     * @param response   响应
     * @throws IOException 异常
     */
    @PostMapping("/api/v1/login")
    public void login(
        @ModelAttribute PasswordLoginModel loginModel,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws IOException {
        AuthenticatedUser<Void> authenticatedUser = userService.login(loginModel.getUsername(), loginModel.getPassword());
        String tgt = sessionManager.setUser(authenticatedUser, request, response);
        generateCodeAndRedirect(loginModel.getRedirectUri(), tgt, response);
    }

    /**
     * 注销登录，重定向到原始调用地址
     *
     * @param logoutModel 注销参数
     * @param request     请求
     * @param response    响应
     * @throws IOException 异常
     */
    @PostMapping("/api/v1/logout")
    public void logout(
        @ModelAttribute LogoutModel logoutModel,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws IOException {
        // 清除登录信息
        // 重定向到登录页面
        removeCodeAndRedirect(logoutModel.getRedirectUri(), logoutModel.getCode(), response);
    }
}
